package cc.ilzy.mall.utils;

import cc.ilzy.mall.exceptions.ExceptionEnum;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 通用响应封装类（支持链式调用）
 * @param <T> 数据类型泛型
 */
@Data
@Accessors(chain = true) // 支持链式调用
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResponse<T> implements Serializable {
    // 常用状态码（可自定义扩展）
    public static final int CODE_SUCCESS = 200;
    public static final int CODE_BAD_REQUEST = 400;
    public static final int CODE_UNAUTHORIZED = 401;
    public static final int CODE_FORBIDDEN = 403;
    public static final int CODE_NOT_FOUND = 404;
    public static final int CODE_SERVER_ERROR = 500;

    //----------------- 核心字段 -----------------//
    /**
     * 状态码 (默认200)
     */
    private int code = CODE_SUCCESS;

    /**
     * 消息描述（前端可直接展示）
     */
    private String message;

    /**
     * 消息键（用于国际化，可选）
     */
    private String messageKey;

    /**
     * 消息参数（用于国际化，可选）
     */
    private Object[] messageArgs;

    /**
     * 响应数据
     */
    private T data;

    private boolean success;

    /**
     * 时间戳
     */
    private LocalDateTime timestamp = LocalDateTime.now();

    /**
     * 是否成功（根据状态码自动计算）
     */
    public boolean isSuccess() {
        return code >= 200 && code < 300;
    }

    //----------------- 静态工厂方法 -----------------//

    /**
     * 成功响应（无数据）
     */
    public static <T> ApiResponse<T> success() {
        return new ApiResponse<T>().setMessage("success").setSuccess(true);
    }

    /**
     * 成功响应（消息体信息）
     */
    public static <T> ApiResponse<T> success(String message) {
        return new ApiResponse<T>().setMessage(message).setSuccess(true);
    }
    /**
     * 成功响应（带数据）
     */
    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<T>().setData(data).setMessage("success").setSuccess(true);
    }

    /**
     * 失败响应（指定状态码和消息）
     */
    public static <T> ApiResponse<T> fail(int code, String message) {
        return new ApiResponse<T>().setCode(code).setMessage(message).setSuccess(false);
    }

    /**
     * 失败响应（根据异常类型自动填充）
     */
    public static <T> ApiResponse<T> fail(Throwable ex) {
        // 可根据异常类型细化状态码（示例逻辑）
        int code = ex instanceof IllegalArgumentException ? CODE_BAD_REQUEST : CODE_SERVER_ERROR;
        return new ApiResponse<T>().setCode(code).setMessage(ex.getMessage()).setSuccess(false);
    }

    /**
     * 失败的响应
     *
     * @param exceptionEnum
     * @param <T>
     * @return
     */
    public static <T> ApiResponse<T> fail(ExceptionEnum exceptionEnum) {
        return ApiResponse.fail(exceptionEnum.getCode(), exceptionEnum.getMessage());
    }


    @Data
    @Accessors(chain = true)
    public static class PageResponse<T> extends ApiResponse<T> {
        /**
         * 分页信息
         */
        private PageInfo page;

        /**
         * 分页信息内部类
         */
        @Data
        public static class PageInfo {
            private int pageNum;    // 当前页
            private int pageSize;   // 每页数量
            private long total;     // 总条数
            private int totalPage;  // 总页数
        }

        /**
         * 创建分页响应
         */
        public static <T> PageResponse<T> page(T data, int pageNum, int pageSize, long total) {
            PageResponse<T> response = new PageResponse<>();
            response.setData(data);
            PageInfo pageInfo = new PageInfo();
            pageInfo.setPageNum(pageNum);
            pageInfo.setPageSize(pageSize);
            pageInfo.setTotal(total);
            pageInfo.setTotalPage((int) Math.ceil((double) total / pageSize));
            response.setPage(pageInfo);
            return response;
        }
    }
}
